#include "input.h"
#include "output.h"
#include "Face.h"
#include "Edge.h"
#include "Vertex.h"
#include <sstream>
#include <fstream>

bool isEdgeExist(std::vector<Edge *>& elist, Edge* e)
{
    for (std::vector<Edge *>::iterator it=elist.begin();it!=elist.end();++it)
    {
        if ((**it)==*e)
        {
            e=(*it);
            return true;
        }
    }
    return false;
}

Edge * addEdge(std::vector<Edge *>& elist, Vertex& v1, Vertex& v2)
{
    static int edgeIdCount=1;
    Edge* eptr=new Edge(edgeIdCount, v1,v2);
    if(!isEdgeExist(elist,eptr))
    {
        elist.push_back(eptr);
        edgeIdCount++;
    }
    return eptr;
}

void addFace(std::vector<Face *>& flist,std::vector<Edge *>&elist, Vertex& v1, Vertex& v2, Vertex& v3)
{
    static int faceIdCount=1;
    flist.push_back(new Face(faceIdCount++,*addEdge(elist,v1,v2), *addEdge(elist,v2,v3), *addEdge(elist,v1,v3)));
}

void processFile(std::string filename,std::vector<Vertex *>& vlist,std::vector<Edge *>& elist,std::vector<Face *>& flist)
{
    std::ifstream infile(filename.c_str(),std::fstream::in);
    std::string line,type;
    int id,id1,id2,id3;
    double x,y,z;

    int outputCount=0;
    while(std::getline(infile,line))
    {
        if (outputCount++%1000==0) std::cout<<outputCount<<std::endl;
        std::istringstream istr(line);
        istr>>type;
        if(type=="Vertex")
        {
            istr>>id>>x>>y>>z;
            vlist.push_back(new Vertex(id,x,y,z));
        }
        if(type=="Face")
        {
            istr>>id>>id1>>id2>>id3;
            addFace(flist,elist,*vlist[--id1],*vlist[--id2],*vlist[--id3]);
        }
    }
    infile.close();
    writeToM((filename+"_p"),vlist,elist,flist);
}


void readData(std::string filename,std::vector<Vertex *>& vlist,std::vector<Edge *>& elist,std::vector<Face *>& flist)
{   
    std::ifstream infile((filename+"_p").c_str(),std::fstream::in);
    if(!infile)
    {
        processFile(filename,vlist,elist,flist);
        return;
    }
    std::string line,type;
    int id,id1,id2,id3;
    double x,y,z;

    while(std::getline(infile,line))
    {
        std::istringstream istr(line);
        istr>>type;
        if(type=="Vertex")
        {
            istr>>id>>x>>y>>z;
            vlist.push_back(new Vertex(id,x,y,z));
        }
        if(type=="Edge")
        {
            istr>>id>>id1>>id2;
            elist.push_back(new Edge(id,*vlist[--id1],*vlist[--id2]));
        }
        if(type=="Face")
        {
            istr>>id>>id1>>id2>>id3;
            flist.push_back(new Face(id,*elist[--id1],*elist[--id2],*elist[--id3]));
        }
    }
    infile.close();
}
